import { NetServices } from "./NetServices";
import { BufferData, GetTypeOf, IMessageSerializeData } from "../../../Decorator/Decorator";
import { SerializeHelper } from "../../Serialize/SerializeHelper";

export class MessageSerializeHelper {

    private static GetStream(count: number = 0) {
        const buffer = new ArrayBuffer(count);
        const view = new DataView(buffer);
        return view;
    }

    public static MessageToStream(message: Object) {
        let type = GetTypeOf(message);
        let opcode = NetServices.Instance.GetOpcode(type);

        let opcodeIndex = 2;
        let msgBuffer = SerializeHelper.Serialize(type, message as BufferData);
        let stream = this.GetStream(opcodeIndex + msgBuffer.byteLength);

        stream.setInt16(0, opcode, true);
        let len = msgBuffer.length;
        for (let i = 0; i < len; i++) {
            let uint8 = msgBuffer[i];
            stream.setUint8(opcodeIndex + i, uint8);
        }
        // console.log(`MessageToStream`);
        // console.log(type);
        // console.log(opcode);
        // console.log(stream.buffer as Buffer);
        // console.log(msgBuffer);

        return { opcode, stream };
    }

    public static StreamToMessage(stream: Uint8Array) {
        let view = new DataView(stream.buffer);
        let opcode = view.getInt16(0, true);
        let msgBuffer = stream.subarray(2);

        let type = NetServices.Instance.GetType(opcode);
        let parentType = NetServices.Instance.GetParentType(type);
        let message = SerializeHelper.Deserialize(type, new Uint8Array(msgBuffer));
        let serializeMessage = <IMessageSerializeData><any>message;
        serializeMessage.Type = type;
        serializeMessage.Parent = parentType;

        return { opcode, serializeMessage };
    }

}